package configs

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"os"
)

//>>>服务配置>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
type AppConf struct {
	Ip   string `json:"ip"`
	Port string `json:"port"`
}

type MysqlConf struct {
	Ip       string `json:"ip"`
	Port     string `json:"port"`
	Username string `json:"username"`
	Password string `json:"password"`
	DB       string `json:"db"`
}

type RedisConf struct {
	Ip       string `json:"ip"`
	Port     string `json:"port"`
	Password string `json:"password"`
	DB string `json:"db"`
}

type ElasticsearchConf struct {
	Ip string `json:"ip"`
	Port string `json:"port"`
}

type AliyunAccessKeyConf struct {
	AccessKeyId     string `json:"access_key_id"`
	AccessKeySecret string `json:"access_key_secret"`
}

type AliyunOssConf struct {
	BucketName  string `json:"bucket_name"`
	ImgFolder   string `json:"img_folder"`
	VideoFolder string `json:"video_folder"`
	FileFolder  string `json:"file_folder"`
	Endpoint    string `json:"endpoint"`
}

type WXConf struct {
	AppId  string `json:"app_id"`
	Secret string `json:"secret"`
}

//>>>环境配置>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

type Conf struct {
	App             AppConf             `json:"app"`
	Mysql           MysqlConf           `json:"mysql"`
	Redis           RedisConf           `json:"redis"`
	Elasticsearch ElasticsearchConf `json:"elasticsearch"`
	AliyunAccessKey AliyunAccessKeyConf `json:"aliyun_access_key"`
	AliyunOss       AliyunOssConf       `json:"aliyun_oss"`
	WX              WXConf              `json:"wx"`
	JwtKey          string              `json:"jwt_key"`
	Sha1Key string `json:"sha1_key"`
}

//>>>总配置>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

type Configs struct {
	Dev  Conf   `json:"dev"`
	Test Conf   `json:"test"`
	Pro  Conf   `json:"pro"`
	Env  string `json:"env"`
}

var (
	conf *Configs
	defConfFilePath = "./app_config.json"
)

func json2struct(jsonstr string, st interface{}) (interface{}, error) {
	err := json.Unmarshal([]byte(jsonstr), st)
	if err != nil {
		return nil, err
	}
	return st, nil
}

func initConf() {
	if conf == nil {
		file, err := os.Open(defConfFilePath)
		if err != nil {
			log.Fatal("读取配置文件失败")
		}
		defer file.Close()
		bt, err := ioutil.ReadAll(file)
		if err != nil {
			log.Fatal("读取配置文件失败")
		}
		conf_json := string(bt)
		conf = &Configs{}
		_, err = json2struct(conf_json, conf)
		if err != nil {
			fmt.Println(err)
			log.Fatal("读取配置文件失败")
		}
	}
}

func init() {
	initConf()
}

func GetAppConf() AppConf {
	initConf()
	c := conf.Dev.App
	if conf != nil {
		switch conf.Env {
		case "dev":
			c = conf.Dev.App
		case "test":
			c = conf.Test.App
		case "pro":
			c = conf.Pro.App
		}
	}
	return c
}

func GetMysqlConf() MysqlConf {
	initConf()
	c := conf.Dev.Mysql
	if conf != nil {
		switch conf.Env {
		case "dev":
			c = conf.Dev.Mysql
		case "test":
			c = conf.Test.Mysql
		case "pro":
			c = conf.Pro.Mysql
		}
	}
	return c
}

func GetRedisConf() RedisConf {
	initConf()
	c := conf.Dev.Redis
	if conf != nil {
		switch conf.Env {
		case "dev":
			c = conf.Dev.Redis
		case "test":
			c = conf.Test.Redis
		case "pro":
			c = conf.Pro.Redis
		}
	}
	return c
}

func GetElasticsearchConf() ElasticsearchConf {
	initConf()
	c := conf.Dev.Elasticsearch
	if conf != nil {
		switch conf.Env {
		case "dev":
			c = conf.Dev.Elasticsearch
		case "test":
			c = conf.Test.Elasticsearch
		case "pro":
			c = conf.Pro.Elasticsearch
		}
	}
	return c
}

func GetAliyunAccessKeyConf() AliyunAccessKeyConf {
	initConf()
	c := conf.Dev.AliyunAccessKey
	if conf != nil {
		switch conf.Env {
		case "dev":
			c = conf.Dev.AliyunAccessKey
		case "test":
			c = conf.Test.AliyunAccessKey
		case "pro":
			c = conf.Pro.AliyunAccessKey
		}
	}
	return c
}

func GetAliyunOssConf() AliyunOssConf {
	initConf()
	c := conf.Dev.AliyunOss
	if conf != nil {
		switch conf.Env {
		case "dev":
			c = conf.Dev.AliyunOss
		case "test":
			c = conf.Test.AliyunOss
		case "pro":
			c = conf.Pro.AliyunOss
		}
	}
	return c
}

func GetWXConf() WXConf {
	initConf()
	c := conf.Dev.WX
	if conf != nil {
		switch conf.Env {
		case "dev":
			c = conf.Dev.WX
		case "test":
			c = conf.Test.WX
		case "pro":
			c = conf.Pro.WX
		}
	}
	return c
}

func GetJwtKeyConf() string {
	initConf()
	c := conf.Dev.JwtKey
	if conf != nil {
		switch conf.Env {
		case "dev":
			c = conf.Dev.JwtKey
		case "test":
			c = conf.Test.JwtKey
		case "pro":
			c = conf.Pro.JwtKey
		}
	}
	return c
}

func GetSha1KeyConf() string {
	initConf()
	c := conf.Dev.Sha1Key
	if conf != nil {
		switch conf.Env {
		case "dev":
			c = conf.Dev.Sha1Key
		case "test":
			c = conf.Test.Sha1Key
		case "pro":
			c = conf.Pro.Sha1Key
		}
	}
	return c
}
